昨天我們聊到 Dynamic Blocks,學會了怎麼在資源內部用迴圈展開子設定,減少重複、讓程式碼更乾淨。
今天我們要來看看 Functions(內建函數)和 Local Values(本地變數)。這兩個東西看似只是輔助工具,但在實務專案裡卻是讓 Terraform 程式碼 「好不好維護」的關鍵差異。
想像幾個常見場景:
[80, 443, 8080] 轉成字串,做為防火牆的名稱一部分。如果全部都硬寫在資源裡,不僅程式碼變醜,日後要改也很麻煩。
這時候,Functions 能幫我們處理「資料運算」,Locals 則能讓程式碼變「乾淨好讀」。
Terraform 提供了上百個內建 Functions,涵蓋 字串、數字、布林、清單、Map、時間、雜湊 等操作。就像程式語言的標準函式庫一樣,能讓我們處理資料更靈活。
以下是一些常見的例子:
variable "env" {
  default = "prod"
}
output "name" {
  value = upper("${var.env}-app")   # => "PROD-APP"
}
upper() → 全部轉大寫lower() → 全部轉小寫replace("hello", "l", "x") → "hexxo"
variable "ports" {
  default = [80, 443, 8080]
}
output "joined_ports" {
  value = join(",", var.ports)   # => "80,443,8080"
join() → 清單轉字串split(",", "80,443,8080") → 還原成 ["80", "443", "8080"]
length(var.ports) → 取得長度(結果是 3)variable "images" {
  default = {
    dev  = "nginx:1.18"
    prod = "nginx:1.24"
  }
}
output "prod_image" {
  value = lookup(var.images, "prod", "nginx:latest")
lookup() 會去 Map 裡找 key,如果找不到,就回傳預設值。
這樣就能避免 key 不存在時 Terraform 出錯。
variable "cidrs" {
  default = ["10.0.0.0/8", "192.168.0.0/16", "0.0.0.0/0"]
}
output "internal_cidrs" {
  value = slice(var.cidrs, 0, 2)   # => ["10.0.0.0/8", "192.168.0.0/16"]
}
slice(list, start, end) → 取子清單contains(list, value) → 檢查是否存在element(list, index) → 取出特定位置元素這些小工具能幫我們省掉大量重複或硬編碼。
Functions 很好用,但如果你在一個資源裡面寫太多函數,程式碼就會變得很亂。
這時候就可以用 Local Values 來先計算,再引用。我們可以把 locals 想成中間變數:
variable "env" {
  default = "prod"
}
locals {
  app_name = "${var.env}-app"
}
resource "google_storage_bucket" "example" {
  name     = local.app_name
  location = "US"
}
之後只要用 local.app_name 就好,不需要在每個地方重複拼接字串。
常見做法是先在 locals 裡,把複雜邏輯收斂起來,主程式碼就保持乾淨:
variable "ports" {
  default = [80, 443, 8080]
}
locals {
  firewall_name = "fw-${replace(join("-", var.ports), "8080", "custom")}"
}
output "result" {
  value = local.firewall_name   # => "fw-80-443-custom"
}
如果沒有 locals,這段邏輯就得直接塞在資源的 name 裡,讀起來非常混亂。
| 特性 | Functions | Local Values | 
|---|---|---|
| 用途 | 處理資料(字串、清單、Map 等) | 封裝計算結果,統一使用 | 
| 範例 | join(",", var.ports) | 
local.app_name = "${var.env}-app" | 
| 適合場合 | 單純轉換、計算時 | 需要重複使用、程式碼過長時 | 
| 優點 | 直接、快速、彈性 | 可讀性高、方便維護 | 
| 缺點 | 太多函數會讓程式碼難讀 | 本身不做運算,還是需要 Functions 搭配 | 
可以這樣理解:
假設我們要建立一台 VM,每個環境的名稱和硬碟大小都不同:
variable "env" {
  default = "dev"
}
locals {
  env_suffix = lower(var.env)
  disk_size  = var.env == "prod" ? 100 : 20
}
resource "google_compute_instance" "example" {
  name         = "app-${local.env_suffix}"
  machine_type = "e2-medium"
  boot_disk {
    initialize_params {
      size = local.disk_size
    }
  }
}
app-dev,磁碟:20GBapp-prod,磁碟:100GB這就是 Functions + Locals 的威力:運算交給 Functions,維護交給 Locals。
今天我們學到:
這些技巧不會改變 Terraform 建立的資源數量,但會大幅提升 可讀性與可維護性,尤其是團隊合作時,大家都能快速理解程式碼的意圖。